import org.lwjgl.util.vector.Vector3f;

class Octree {
	
	private boolean m_isLeaf;
	private Vector3f m_center;
	private float m_bbSize;
	private final int TOP_FRONT_LEFT = 0;
	private final int TOP_FRONT_RIGHT = 1;
	private final int TOP_BACK_LEFT = 2;
	private final int TOP_BACK_RIGHT = 3;
	private final int BOTTOM_FRONT_LEFT = 4;
	private final int BOTTOM_FRONT_RIGHT = 5;
	private final int BOTTOM_BACK_LEFT = 6;
	private final int BOTTOM_BACK_RIGHT = 7;
	
	Octree[] m_childNodes = new Octree[8];
	
	public Octree() {
		m_isLeaf = false;
		m_bbSize = 0;
		
		for( int i = 0; i < 8; i++ ) {
//			m_childNodes[i] = 0;
		}
	}
	
	public void createNode(Vector3f center, float bbSize, int currentLevel, int maxLevel) {
		
		m_bbSize = bbSize;
		m_center = center;
		
		if( currentLevel >= maxLevel ) {
			m_isLeaf = true;
			return;
		}
		
		float newSize = bbSize / 4;
		m_isLeaf = false;
		
		Vector3f topFrontLeft = new Vector3f(-newSize, newSize,  newSize);
		Vector3f topFrontRight = new Vector3f( newSize, newSize,  newSize);
		Vector3f topBackLeft = new Vector3f(-newSize, newSize, -newSize);
		Vector3f topBackRight = new Vector3f(newSize, newSize,  -newSize);
		Vector3f bottomFrontLeft = new Vector3f(-newSize, -newSize,  newSize);
		Vector3f bottomFrontRight = new Vector3f( newSize, -newSize,  newSize);
		Vector3f bottomBackLeft = new Vector3f(-newSize, -newSize, -newSize);
	   	Vector3f bottomBackRight = new Vector3f( newSize, -newSize, -newSize);
	   	
	   	m_childNodes[TOP_FRONT_LEFT] = new Octree();
	    m_childNodes[TOP_FRONT_RIGHT] = new Octree();
	    m_childNodes[TOP_BACK_LEFT] = new Octree();
	    m_childNodes[TOP_BACK_RIGHT] = new Octree();
	    m_childNodes[BOTTOM_FRONT_LEFT] = new Octree();
	    m_childNodes[BOTTOM_FRONT_RIGHT] = new Octree();
	    m_childNodes[BOTTOM_BACK_LEFT] = new Octree();
	    m_childNodes[BOTTOM_BACK_RIGHT] = new Octree();
	    
	   	Vector3f v = new Vector3f();
	   	
	   	currentLevel++;
	   	Vector3f.add(m_center, topFrontLeft, v);
	   	m_childNodes[TOP_FRONT_LEFT].createNode(v, bbSize / 2, currentLevel, maxLevel);
	    currentLevel--;

	    currentLevel++;
	   	Vector3f.add(m_center, topFrontRight, v);
	    m_childNodes[TOP_FRONT_RIGHT].createNode(v, bbSize / 2, currentLevel, maxLevel);
	    currentLevel--;

	    currentLevel++;
	   	Vector3f.add(m_center, topBackLeft, v);
	    m_childNodes[TOP_BACK_LEFT].createNode(v, bbSize / 2, currentLevel, maxLevel);
	    currentLevel--;

	    currentLevel++;
	   	Vector3f.add(m_center, topBackRight, v);
	    m_childNodes[TOP_BACK_RIGHT].createNode(v, bbSize / 2, currentLevel, maxLevel);
	    currentLevel--;

	    currentLevel++;
	   	Vector3f.add(m_center, bottomFrontLeft, v);
	    m_childNodes[BOTTOM_FRONT_LEFT].createNode(v, bbSize / 2, currentLevel, maxLevel);
	    currentLevel--;

	    currentLevel++;
	   	Vector3f.add(m_center, bottomFrontRight, v);
	    m_childNodes[BOTTOM_FRONT_RIGHT].createNode(v, bbSize / 2, currentLevel, maxLevel);
	    currentLevel--;

	    currentLevel++;
	   	Vector3f.add(m_center, bottomBackLeft, v);
	    m_childNodes[BOTTOM_BACK_LEFT].createNode(v, bbSize / 2, currentLevel, maxLevel);
	    currentLevel--;

	    currentLevel++;
	   	Vector3f.add(m_center, bottomBackRight, v);
	    m_childNodes[BOTTOM_BACK_RIGHT].createNode(v, bbSize / 2, currentLevel, maxLevel);
	    currentLevel--;
	}
	
	/**
	 * GETTER SETTERS
	 */


    public boolean isLeaf() { return m_isLeaf; }
    public Vector3f GetCenter() { return m_center; }
    public float GetSize() { return m_bbSize; }
    public Octree[] GetSubNodes() { return m_childNodes; }
}